package org.example.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.pojo.tes.Vulnerability;
import org.example.pojo.tes.Affected;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CveDataFetcherService {

    private static final String CVE_API_URL = "https://services.nvd.nist.gov/rest/json/cves/2.0/?pubStartDate=2023-01-01T00:00:00.000&pubEndDate=2024-03-11T00:00:00.000&resultsPerPage=10";//"https://cve.circl.lu/api/vulnerability/recent/10";
//    @Autowired
//    private static ObjectMapper objectMapper;
    public static void main(String[] args) throws JsonProcessingException {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(CVE_API_URL, String.class);
        String json = response.getBody();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        List<Vulnerability> vulnerabilities = objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, Vulnerability.class));
        for (Vulnerability vulnerability : vulnerabilities) {
            String cveId = vulnerability.getCveMetadata().getCveId();
            String title = vulnerability.getContainers().getCna().getTitle();
            String description = "";
            if (vulnerability.getContainers().getCna().getDescriptions() != null) {
                description = vulnerability.getContainers().getCna().getDescriptions().get(0).getValue();
            }
            List<String> affectedProducts = vulnerability.getContainers().getCna().getAffected().stream()
                    .map(Affected::getProduct)
                    .collect(Collectors.toList());
            String severity = "UNKNOWN";
            if(vulnerability.getContainers().getCna().getMetrics() != null) {
                severity = vulnerability.getContainers().getCna().getMetrics().get(0).getCvssV3_1().getBaseSeverity();
            }
            double score = 0.0;
            if (vulnerability.getContainers().getCna().getMetrics() != null) {
                score = vulnerability.getContainers().getCna().getMetrics().get(0).getCvssV3_1().getBaseScore();
            }
            String suggestion = "";
            if (vulnerability.getContainers().getCna().getReference() != null) {
                suggestion = vulnerability.getContainers().getCna().getReference().get(0).getUrl();
            }
            String publishedDate = vulnerability.getCveMetadata().getDatePublished();
            System.out.println("漏洞 ID: " + cveId);
            System.out.println("名称: " + title);
            System.out.println("描述: " + description);
            System.out.println("受影响产品: " + affectedProducts);
            System.out.println("严重等级: " + severity);
            System.out.println("CVSS评分: " + score);
            System.out.println("修复建议: " + suggestion);
            System.out.println("发布时间: " + publishedDate);
            System.out.println("----------------------");
        }
    }

    @Scheduled(fixedRate = 60000) // 每小时执行一次
    public void fetchCveData() {
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> response = restTemplate.getForObject(CVE_API_URL, Map.class);
        if (response != null && response.containsKey("vulnerabilities")) {
            for (Object vulnerabilityObj : (Iterable<?>) response.get("vulnerabilities")) {
                Map<String, Object> vulnerability = (Map<String, Object>) vulnerabilityObj;
                Map<String, Object> cve = (Map<String, Object>) vulnerability.get("cve");

                // 提取关键信息
                String cveId = (String) cve.get("id");
                String publishTime = (String) cve.get("published");
                String vulnStatus = (String) cve.get("vulnStatus");
                String description = "";
                if (cve.containsKey("descriptions")) {
                    for (Object descriptionObj : (Iterable<?>) cve.get("descriptions")) {
                        Map<String, Object> desc = (Map<String, Object>) descriptionObj;
                        if ("en".equals(desc.get("lang"))) {
                            description = (String) desc.get("value");
                            break;
                        }
                    }
                }

                String severity = "";
                double cvssScore = 0.0;
                if (cve.containsKey("metrics")) {
                    Map<String, Object> metrics = (Map<String, Object>) cve.get("metrics");
                    if (metrics.containsKey("cvssMetricV31")) {
                        for (Object cvssMetricObj : (Iterable<?>) metrics.get("cvssMetricV31")) {
                            Map<String, Object> cvssMetric = (Map<String, Object>) cvssMetricObj;
                            Map<String, Object> cvssData = (Map<String, Object>) cvssMetric.get("cvssData");
                            severity = (String) cvssData.get("baseSeverity");
                            cvssScore = Double.parseDouble(cvssData.get("baseScore").toString());
                            break;
                        }
                    }
                }

                String affectedProducts = "";
                if (cve.containsKey("configurations")) {
                    // 解析受影响产品的逻辑可以根据实际需求进一步完善
                    // 这里只是简单示例
                    affectedProducts = cve.get("configurations").toString();

                }

                System.out.println("CVE ID: " + cveId);
                System.out.println("Description: " + description);
                System.out.println("Severity: " + severity);
                System.out.println("CVSS Score: " + cvssScore);
                System.out.println("Affected Products: " + affectedProducts);
                System.out.println("---------------------");
            }
        }
    }
}